package com.clss.commandhelper.function.videoroom;

import android.text.TextUtils;

import com.clss.commandhelper.base.BaseJson;
import com.clss.commandhelper.base.BasePresenter;
import com.clss.commandhelper.base.BaseView;
import com.clss.commandhelper.net.ApiConstants;
import com.clss.commandhelper.tools.Constant;
import com.clss.commandhelper.tools.Lg;
import com.clss.commandhelper.tools.SpHelper;
import com.clss.commandhelper.tools.UploadHelper;
import com.clss.commandhelper.tools.Utils;
import com.clss.commandhelper.tools.eventbus.EventBusHelper;
import com.clss.commandhelper.tools.janus.entity.MediaSessionBean;
import com.google.common.collect.Lists;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.annotations.Nullable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import okhttp3.WebSocket;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import ua.naiksoftware.stomp.Stomp;
import ua.naiksoftware.stomp.StompHeader;
import ua.naiksoftware.stomp.client.StompClient;
import ua.naiksoftware.stomp.client.StompMessage;

/**
 *
 * Created by Administrator on 2017/6/1.
 */

public class WebRtcPresenter extends BasePresenter {
    private static final String TAG = "WebRtcPresenter";

    private static final int MAX_RETRY_NUMBER = 10;

    public static final int CHAT_TYPE_CALL = 1;
    public static final int CHAT_TYPE_CHAT = 2;

    public static final String HEART_BEAT_VALUE = "0,10000";

    private WebRtcView mWebRtcView;
    private WebRtcModel mWebRtcModel;
    private StompClient mStompClient;
    private String mChatId;  //chatId
    private String mUploadImagePath;
    private ChatMsgTextEntity mLastMsgEntity;
    private int mRetryWebSocketConnectionNumber;
    private int mChatType = 0;
    private long mSendVoiceTag = 0;

    public WebRtcPresenter(int chatType) {
        this.mChatType = chatType;
    }

    public void setmWebRtcView(WebRtcView mWebRtcView) {
        this.mWebRtcView = mWebRtcView;
        mContext = mWebRtcView.getActContext();
    }

    //创建文字通信房间的回调
    private Callback<BaseJson> mCreatChatCallback = new Callback<BaseJson>() {
        @Override
        public void onResponse(Call<BaseJson> call, Response<BaseJson> response) {
            BaseJson baseJson = response.body();
            EventBusHelper.handleBaseJson(baseJson);
            Lg.i(TAG, "---baseJson==1==" + baseJson);
            if (baseJson != null){
                if (baseJson.getCode() != 0){
                    mWebRtcView.responseError(baseJson.getCode(), baseJson.getError());
                }else {
                    mChatId = mGson.fromJson(baseJson.getObj(), String.class);
                    mWebRtcView.createChatSuccess(mChatId);
                    connectChat();
                }
            }else {
                mWebRtcView.responseError(Constant.UNKNOW_ERROR_CODE, Constant.UNKNOW_ERROR_MESSAGE);
            }
        }

        @Override
        public void onFailure(Call<BaseJson> call, Throwable t) {
            mWebRtcView.requestFailure(t);
        }
    };

    public CreateChatEntity createChat(MediaSessionBean entity, boolean isTest){
        if (mWebRtcModel == null){
            mWebRtcModel = new WebRtcModel(mWebRtcView.getActContext());
        }
        String[] creators = {entity.getCreator()};

        CreateChatEntity createChatEntity = new CreateChatEntity();
        createChatEntity.setId(entity.getId());
        createChatEntity.setName("实时报警");
        createChatEntity.setInvitee(Arrays.asList(creators));
        createChatEntity.setCreator(new CreateChatEntity.CreatorBean(entity.getCreator()));
        createChatEntity.setInviter(new CreateChatEntity.InviterBean(entity.getCreator()));

        String token = SpHelper.getInstance().getToken();

//        mWebRtcModel.createChat(token, createChatEntity, mCreatChatCallback);
        return createChatEntity;
    }

    private void connectChat(){
        Map<String, String> header = new HashMap<>();
        header.put(Constant.APP_TOKEN, SpHelper.getInstance().getToken());
        mStompClient = Stomp.over(WebSocket.class, ApiConstants.getStompApiHost(), header);

        List<StompHeader> stompHeaders = Lists.newArrayList(new StompHeader(StompHeader.HEART_BEAT, HEART_BEAT_VALUE));
        setChatConnectionStatusListener();
        mStompClient.connect(stompHeaders);
    }

    public void stopChat(){
        Lg.i(TAG, "---disconnect===");
        if (mStompClient != null && mStompClient.isConnected()) {
            sendChatMsg(SpHelper.getInstance().getUserName() + "已退出", mWebRtcView.isTest());
        }
        if (mStompClient != null){
            mStompClient.disconnect();
        }
    }

    public void reconnectChat(String id){
        Lg.i(TAG, "---reconnectChat===" + id);
        mRetryWebSocketConnectionNumber++;
        mChatId = id;
        connectChat();
    }

    private void setChatConnectionStatusListener(){
        mStompClient
                .lifecycle()
                .subscribe(lifecycleEvent -> {
//                                   LifecycleEvent event = lifecycleEvent;
//                                    Lg.i(TAG, "---lifecycleEvent.getHandshakeResponseHeaders===" + lifecycleEvent.getHandshakeResponseHeaders().toString());
//                                   Lg.i(TAG, "---setChatConnectionStatusListener===111==" + lifecycleEvent.toString());
                    switch (lifecycleEvent.getType()) {
                        case OPENED:
                            Lg.i(TAG, "---OPENED===");
                            mWebRtcView.chatConnectionStart();
                            setChatReceiveListener(mChatId);
                            break;
                        case ERROR:
                            Lg.i(TAG, "---ERROR===");
                            mWebRtcView.chatConnectionError();
                            if (mRetryWebSocketConnectionNumber > MAX_RETRY_NUMBER) {
                                mRetryWebSocketConnectionNumber = 0;
                                return;
                            }
                            reconnectChat(mChatId);
                            break;
                        case CLOSED:
                            Lg.i(TAG, "---CLOSED===");
                            mWebRtcView.chatConnectionStop();
                            break;
                        default:
                    }
//                                   Lg.i(TAG, "---lifecycleEvent.getMessage===" + lifecycleEvent.getMessage());
//                                   Lg.i(TAG, "---lifecycleEvent.getException===" + lifecycleEvent.getException().getMessage());
                },
                        new Consumer<Throwable>() {
                            @Override
                            public void accept(Throwable throwable) throws Exception {
                                Lg.i(TAG, "---setChatConnectionStatusListener===222==" + throwable.getMessage());
                            }
                        }, new Action() {
                            @Override
                            public void run() throws Exception {
                                Lg.i(TAG, "---setChatConnectionStatusListener===Action==" );
                            }
                        });
    }

    private void setChatReceiveListener(String id){
        mStompClient
                .topic(Constant.CHAT_TOPIC + id)
                .subscribe(stompMessage -> {
                    ChatMsgTextEntity entity = mGson.fromJson(stompMessage.getPayload(), ChatMsgTextEntity.class);
                    if (Constant.CHAT_LOGOUT.equals(entity.getEvent())){
                        mWebRtcView.chatIsLogout();
                        return;
                    }
                    @Nullable String text = entity.getBody().getText();
                    if (!TextUtils.isEmpty(text)){
                        if (text.contains(Constant.SEND_IMAGE_MSG_TAG_START) ||
                                text.contains(Constant.SEND_VIDEO_MSG_TAG_START)){
                            mWebRtcView.chatHasNewMsg(entity, mUploadImagePath);
                            mUploadImagePath = "";
                            return;
                        }
//                        if (text.contains(Constant.SEND_VOICE_MSG_TAG_START) && mSendVoiceTag > 0){
//                            mWebRtcView.chatHasNewMsg(entity, null);
//                            return;
//                        }
                        if (text.contains(Constant.SEND_ADDRESS_MSG_TAG_END)){
                            String address = entity.getBody()
                                    .getText()
                                    .replace(Constant.SEND_ADDRESS_MSG_TAG_START, "")
                                    .replace(Constant.SEND_ADDRESS_MSG_TAG_END, "");
                            entity.getBody().setText("事发地址上报为\n" + address);
                        }else if (text.contains(Constant.SEND_LATLNG_MSG_TAG_END)){
                            return;
                        }
                    }
                    mWebRtcView.chatHasNewMsg(entity, null);
                });
    }

    public void sendChatMsg(final String msg, boolean isTest){
        ChatMsgTextEntity.BodyBean bodyBean =
                new ChatMsgTextEntity.BodyBean(SpHelper.getInstance().getUserId(), msg, SpHelper.getInstance().getUserName(), Utils.getNowTime());
        ChatMsgTextEntity entity = new ChatMsgTextEntity(SpHelper.getInstance().getUserId(), isTest ? Constant.CHAT_TEST : Constant.CHAT_MESSAGE, bodyBean);
        mLastMsgEntity = entity;
        Lg.i(TAG, "---sendChatMsg===" + mLastMsgEntity);
        String sendMsg = mGson.toJson(entity);
        mStompClient.send(Constant.CHAT_TOPIC + mChatId, sendMsg)
                .subscribe(new Subscriber<Void>() {

                    @Override
                    public void onError(Throwable e) {
                        mWebRtcView.chatSendMsgError(msg, e);
                    }

                    @Override
                    public void onComplete() {
                        if (msg.contains(Constant.SEND_IMAGE_MSG_TAG_END)){
                            return;
                        }
                        mWebRtcView.chatSendMsgSuccess(mLastMsgEntity);
                    }

                    @Override
                    public void onSubscribe(Subscription s) {

                    }

                    @Override
                    public void onNext(Void aVoid) {

                    }
                });
    }

    public void sendImageMsg(String path){
        File file = new File(path);
        mUploadImagePath = path;
        UploadHelper.uploadImage(file, ApiConstants.getUploadImageUrl(), new okhttp3.Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {

            }

            @Override
            public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
                String responseBody = response.body().string();
                BaseJson baseJson = mGson.fromJson(responseBody, BaseJson.class);
                if (baseJson.getCode() == 201){
                    JsonElement jsonElement = (JsonElement) baseJson.getList().get(0);
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    String imageId = jsonObject.get("id").getAsString();
                    sendChatMsg(Constant.SEND_IMAGE_MSG_TAG_START
                                    + imageId + Constant.SEND_IMAGE_MSG_TAG_END,
                            mWebRtcView.isTest());
                }else {

                }
            }
        });
    }

    public void sendVideoMsg(String path){
        File file = new File(path);
        mUploadImagePath = path;
        UploadHelper.uploadImage(file, ApiConstants.getUploadImageUrl(), new okhttp3.Callback() {
            @Override
            public void onFailure(okhttp3.Call call, IOException e) {

            }

            @Override
            public void onResponse(okhttp3.Call call, okhttp3.Response response) throws IOException {
                String responseBody = response.body().string();
                BaseJson baseJson = mGson.fromJson(responseBody, BaseJson.class);
                if (baseJson.getCode() == 201){
                    JsonElement jsonElement = (JsonElement) baseJson.getList().get(0);
                    JsonObject jsonObject = jsonElement.getAsJsonObject();
                    String videoId = jsonObject.get("id").getAsString();
                    sendChatMsg(Constant.SEND_VIDEO_MSG_TAG_START
                                    + videoId + Constant.SEND_VIDEO_MSG_TAG_END,
                            mWebRtcView.isTest());
                }else {

                }
            }
        });
    }

    public long sendVoiceMessage(String voicePath){
        mSendVoiceTag = System.currentTimeMillis();
        SecurityUploadService.startActionFoo(mWebRtcView.getActContext(),
                voicePath, mSendVoiceTag, Utils.checkFileType(voicePath));
        return mSendVoiceTag;
    }

    @Override
    public void cancelCall() {

    }

    public interface WebRtcView extends BaseView {
        void createChatSuccess(String id);
        void chatConnectionStart();
        void chatConnectionStop();
        void chatConnectionError();
        void chatHasNewMsg(ChatMsgTextEntity msgTextEntity, String filePath);
        void chatSendMsgSuccess(ChatMsgTextEntity msgTextEntity);
        void chatSendMsgError(String msg, Throwable e);
        boolean isTest();
        void chatIsLogout();
        String getCallType();
    }
}
